#include <iostream>
#include <cstdlib>
#include <ctime>
#include "graph.h"
#include <string>

// UNCOMMENT FOR NEW MENU
//#define WIN_MENU

#ifdef WIN_MENU
	#include "interface.h"
#endif

using namespace std;

int main(int argc, char* argv[]){
    graph g;
	char nazwa[70];
	int v1, v2, result;


#ifdef WIN_MENU
	//char nazwa2[40];
	char filename[70] = "\0";
    



	//MENU - interface 

	const int POZ_MENU[3]={9,4,4};
	string menu[3][10]={{"Wybierz plik do wczytania",
					"Utworz macierz sasiedztwa",
					"Utworz liste sasiedztwa",
					"Utworz dynamiczna macierz listowa",
					"Djikstra",
					"Bellman-ford",
					"Trzeci algorytm",
					"Czwarty algorytm",
					"Zakoncz program"},
					{"Dijkstra: Macierz sasiedztwa",
					 "Dijkstra: adj_list sasiedztwa",
					 "Dijkstra: Dynamiczna macierz listowa",
					 "Powrot"
					},
					{"Bellman-ford: Macierz sasiedztwa",
					 "Bellman-ford: lista sasiedztwa",
					 "Bellman-ford: Dynamiczna macierz listowa",
					 "Powrot"
					}};

	short active = 0;
	char key;
	short menu_level = 0;

	//MENU - interface


////!!!!!!COMMENT FOR NEW MENU
//goto OLDMENU;
////!!!!!!
//NEWMENU:

	writetab(menu[menu_level],POZ_MENU[menu_level], active, nazwa);


	while(1){
	key=getkey();

	system("cls");

	switch(key)
	{
		case 72:	//Strzalka w dol
			if(active!=0)
				active--;
			break;
		case 80:	//Strzalka w gore
			if(active<POZ_MENU[menu_level]-1)
				active++;
			break;
		case 13:	//ENTER
			switch(menu_level)
			{
			case 0:
				switch(active)
				{
					case(0):
						 setcolor(7);
						 cout << "Filename:/";
						 setcolor(8);
						 cin >> filename;
						 setcolor(7);				
						system("cls");
						break;
					case(1):
						setcolor(7);
						cout<<"Loading...\n";
						g.t_start();
						g.load_matrix(filename);
						g.t_stop();
						cout << "Finished! time:" << g.t_ms << "ms "<< endl;
						system("pause");					
						system("cls");
						break;
					case(2):
						setcolor(7);
						cout<<"Loading...\n";
						g.t_start();
						g.load_list(filename);
						g.t_stop();
						cout << "Finished! time:" << g.t_ms << "ms "<< endl;
						system("pause");					
						system("cls");
						break;
					case(3):
						setcolor(7);
						cout<<"Loading...\n";
						g.t_start();
						g.load_vector(filename);
						g.t_stop();
						cout << "Finished! time:" << g.t_ms << "ms "<< endl;
						system("pause");					
						system("cls");
						break;			
					case(4):
						menu_level = 1;
						active = 0;
						break;
					case(5):
						menu_level = 2;
						active = 0;
						break;
					case(8):
						return 0;
					default:
						break;
				}
				break;
			case 1:				
				switch(active)
				{
					case(0):
						 setcolor(7);
						 cout<<"Type start and end vertex ";
						 setcolor(8);
						 cin >> v1;
						 cin >> v2;
						 g.t_start();
						 result = g.dijkstra_matrix(v1, v2);
						 g.t_stop();
						 setcolor(7);
		   				 cout << "Dijkstra: " << result << " " << g.t_ms << "ms" << endl;
						 system("pause");
						 system("cls");
						  break;
					case(1):
						 setcolor(7);
						 cout<<"Type start and end vertex ";
						 setcolor(8);
						 cin >> v1;
						 cin >> v2;
						 g.t_start();
						 result = g.dijkstra_list(v1, v2);
						 g.t_stop();
						 setcolor(7);
		   				 cout << "Dijkstra: " << result << " " << g.t_ms << "ms" << endl;
						 system("pause");
						 system("cls");
						  break;
					case(2):
						 setcolor(7);
						 cout<<"Type start and end vertex ";
						 setcolor(8);
						 cin >> v1;
						 cin >> v2;
						 g.t_start();
						 result = g.dijkstra(v1, v2);
						 g.t_stop();
						 setcolor(7);
		   				 cout << "Dijkstra: " << result << " " << g.t_ms << "ms" << endl;
						 system("pause");
						 system("cls");
						  break;
					case(3):
						menu_level = 0;
						active = 0;
						break;
					default:
						break;
					
				}
				break;
			case 2:				
				switch(active)
				{
					case(0):
						 setcolor(7);
						 cout<<"Type start and end vertex ";
						 setcolor(8);
						 cin >> v1;
						 cin >> v2;
						 g.t_start();
						 result = g.bellman_ford_matrix(v1, v2);
						 g.t_stop();
						 setcolor(7);
		   				 cout << "Bellman_ford: " << result << " " << g.t_ms << "ms" << endl;
						 system("pause");
						 system("cls");
						  break;
					case(1):
						 setcolor(7);
						 cout<<"Type start and end vertex ";
						 setcolor(8);
						 cin >> v1;
						 cin >> v2;
						 g.t_start();
						 result = g.bellman_ford_list(v1, v2);
						 g.t_stop();
						 setcolor(7);
		   				 cout << "Bellman_ford: " << result << " " << g.t_ms << "ms" << endl;
						 system("pause");
						 system("cls");
						  break;
					case(2):
						 setcolor(7);
						 cout<<"Type start and end vertex ";
						 setcolor(8);
						 cin >> v1;
						 cin >> v2;
						 g.t_start();
						 result = g.bellman_ford(v1, v2);
						 g.t_stop();
						 setcolor(7);
		   				 cout << "Bellman_ford: " << result << " " << g.t_ms << "ms" << endl;
						 system("pause");
						 system("cls");
						  break;
					case(3):
						menu_level = 0;
						active = 0;
						break;
					default:
						break;					
				}
				break;

			
			default:
				break;
			}
		default:
			break;
	}
	
	writetab(menu[menu_level],POZ_MENU[menu_level], active, filename);
	}

//Zamykanie programu-----


	//OLDMENU:

	//cout<<"a for new menu\n";
#endif

#ifndef WIN_MENU
	
	int wybor;
    
	enum { HELP = 0,
		   L_V = 11, L_M, L_L,
		   P_V = 21, P_M, P_L,
		   DIJ_V = 31, DIJ_M, DIJ_L,
	       BL_V = 41, BL_M, BL_L,
		   KR_V = 51, KR_M, 
		   PR_V = 61, PR_M,
		   Q_T = 71, C_T,
	       QUIT = 9};

	do{
		//cin.ignore(100);
        cin >> wybor;

        switch(wybor){

			default:
				cout << "no such option" << endl;
				break;

            case QUIT:
                break;

            case HELP:
                cout << HELP << " - help" << endl
                     << L_V  << "- load adj_vector" << endl
                     << L_M  << "- load adj_matrix" << endl
					 << L_L  << "- load adj_list" << endl
					 << P_V  << "- print adj_vector" << endl
					 << P_M  << "- print adj_matrix" << endl
					 << P_L  << "- print adj_list" << endl
					 << DIJ_V << "- DIJ_V "<< endl
					 << DIJ_M << "- DIJ_M" << endl
					 << DIJ_L << "- DIJ_L" << endl
					 << BL_V << "- BL_V "<< endl
					 << BL_M << "- BL_M" << endl
					 << BL_L << "- BL_L" << endl
					 << KR_V << "- KR_V "<< endl
					 << KR_M << "- KR_M "<< endl
					 << PR_V << "- PR_V "<< endl
					 << PR_M << "- PR_M "<< endl
					 << Q_T <<" - queue tests" << endl
					 << C_T <<" - clock test" << endl
					 << QUIT << " - quit" << endl;
                break;

            case L_V:
                //cout << ":/";
                cin >> nazwa;
				g.t_start();
                g.load_vector(nazwa);
				g.t_stop();
				//cout << "finished! time:" << g.t_ms << "ms "<< endl;
                break;

			case L_M:
                //cout << ":/";
                cin >> nazwa;
				g.t_start();
                g.load_matrix(nazwa);
				g.t_stop();
				//cout << "finished! time:" << g.t_ms << "ms "<< endl;
                break;

			case L_L:
                cout << ":/";
                cin >> nazwa;
				g.t_start();
                g.load_list(nazwa);
				g.t_stop();
				//cout << "finished! time:" << g.t_ms << "ms "<< endl;
                break;

			case P_V:
                g.print_vector();
                break;

			case P_M:
                g.print_matrix();
                break;

            case P_L:
                g.print_list();
                break;
				
            case DIJ_V:
                cin >> v1;
                cin >> v2;
				g.t_start();
                result = g.dijkstra(v1, v2);
				g.t_stop();
				cout << "DIJ_V;" << nazwa << ";" << g.getV() << ";" << g.getE() << ";" << result << ";" << g.t_ms << ";us;" << endl;
                break;

              case DIJ_M:
                cin >> v1;
                cin >> v2;
				g.t_start();
                result = g.dijkstra_matrix(v1, v2);
				g.t_stop();
				cout << "DIJ_M;" << nazwa << ";" <<  g.getV() << ";" << g.getE() << ";" << result << ";" << g.t_ms << ";us;" << endl;
                break;

            case DIJ_L:
                cin >> v1;
                cin >> v2;
				g.t_start();
                result = g.dijkstra_list(v1, v2);
				g.t_stop();
				cout << "DIJ_L;" << nazwa << ";" << g.getV() << ";" << g.getE() << ";" << result << ";" << g.t_ms << ";us;" << endl;
                break;

			case BL_V:
                cin >> v1;
                cin >> v2;
				g.t_start();
                result = g.bellman_ford(v1, v2);
				g.t_stop();
				cout << "BL_V;" << nazwa << ";" << g.getV() << ";" << g.getE() << ";" << result << ";" << g.t_ms << ";us;" << endl;
                break;

			case BL_M:
                cin >> v1;
                cin >> v2;
				g.t_start();
                result = g.bellman_ford_matrix(v1, v2);
				g.t_stop();
				cout << "BL_M;" << nazwa << ";" << g.getV() << ";" << g.getE() << ";" << result << ";" << g.t_ms << ";us;" << endl;
                break;


			case BL_L:
                cin >> v1;
                cin >> v2;
				g.t_start();
                result = g.bellman_ford_list(v1, v2);
				g.t_stop();
				cout << "BL_L;" << nazwa << ";" << g.getV() << ";" << g.getE() << ";" << result << ";" << g.t_ms << ";us;" << endl;
                break;

			case KR_V:
				g.t_start();
				result = g.mst_kruskal();
				g.t_stop();
				cout << "KR_V;" << nazwa << ";" << g.getV() << ";" << g.getE() << ";" << result << ";" << g.t_ms << ";us;" << endl;
				break;

			case KR_M:
				g.t_start();
				result = g.mst_kruskal_matrix();
				g.t_stop();
				cout << "KR_M;" << nazwa << ";" << g.getV() << ";" << g.getE() << ";" << result << ";" << g.t_ms << ";us;" << endl;
				break;

			case PR_V:
				cin >> v1;
				g.t_start();
				result = g.mst_prim(v1);
				g.t_stop();
				cout << "PR_V;" << nazwa << ";" << g.getV() << ";" << g.getE() << ";" << result << ";" << g.t_ms << ";us;" << endl;
				break;

			case PR_M:
				cin >> v1;
				g.t_start();
				result = g.mst_prim_matrix(v1);
				g.t_stop();
				cout << "PR_M;" << nazwa << ";" << g.getV() << ";" << g.getE() << ";" << result << ";" << g.t_ms << ";us;" << endl;
				break;

            case Q_T:
				srand((unsigned int) time(NULL));
                g.queue_tests();
                break;


			case C_T:
                g.t_test();
                break;
        }

    }while(wybor!=QUIT);

#endif
}
